package pers.bc.utils.yonyou;
 
import java.io.File;
import java.util.ArrayList; 
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.springframework.util.StopWatch;

import nc.bs.framework.common.InvocationInfo;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.pub.pa.PreAlertObject;
import nc.bs.pub.pa.PreAlertReturnType;
import nc.bs.pub.taskcenter.BgWorkingContext;
import nc.bs.pub.taskcenter.IBackgroundWorkPlugin;
import nc.vo.pub.BusinessException;
import pers.bc.utils.constant.IPubCons;
import pers.bc.utils.pub.JsonUtil;
import pers.bc.utils.pub.JudgeAssertUtil;
import pers.bc.utils.pub.LoggerAbs;
import pers.bc.utils.pub.LoggerUtil;
import pers.bc.utils.pub.PubEnvUtil;
import pers.bc.utils.pub.StringUtil;
import pers.bc.utils.thread.IThreadTask;
import pers.bc.utils.thread.MultiThreadUtils;
import pers.bc.utils.thread.ThreadResultBean;

public class BackgroundWorkTaskPlugin implements IBackgroundWorkPlugin
{
    
    private String taskName = "****后台定时任务";
    private String checkthrow = "checkthrow";
    private String pk_group = "00000000000000000001";
    private final Lock lock = new ReentrantLock();
    
    protected LinkedHashMap<String, Object> argsMap;
    protected volatile List<String> msgList = new ArrayList();
    protected String folder = "MyLogs";
    private LoggerUtil logUtil = LoggerUtil.getInstance(folder);
    private long logTraceId = System.currentTimeMillis();;
    
    /**
     * *********************************************************** <br>
     * *说明： 后台任务运行方法 二开重写此方法 <br>
     * 
     * @see <br>
     * @param args
     * @throws Exception <br>
     * @void <br>
     * @methods pers.bc.utils.yonyou.BackgroundWorkTaskPlugin#runing <br>
     * @author LiBencheng <br>
     * @date Created on 2024年1月22日 <br>
     * @time 13:48:39 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    protected void runing(BgWorkingContext args) throws Exception
    {
        StopWatch watch = new StopWatch();
        watch.start();
        // 重写此方法，示例任务代码如下，自行加锁
        try
        {
            lock.lock();
            if (PubEnvUtil.equals(argsMap.get("multithread"), IPubCons.TRUE) || PubEnvUtil.equals(argsMap.get("multithread"), IPubCons.Y))
            {
                // start
                List<Integer> data = new ArrayList(100);
                // 辅助参数:加数
                Map<String, Object> params = new HashMap();
                params.put("addNum", 4);
                MultiThreadUtils<Integer> threadUtil = MultiThreadUtils.newInstance(0);
                threadUtil.execute(data, params, new IThreadTask<ThreadResultBean<Object>, Integer>()
                {
                    @Override
                    public ThreadResultBean<Object> execute(Integer e, Map<?, ?> params)
                    {
                        ThreadResultBean<Object> resultBean = ThreadResultBean.newInstance();
                        
                        // 这里写你的业务代码
                        // ...
                        
                        resultBean.setThreadName(StringUtil.toString(params.get("threadName")));
                        return resultBean;
                    }
                });
            }
            else
            { // 这里写你的业务代码
              // ...
            }
            // end
            
        }
        catch (Exception e)
        {
            JudgeAssertUtil.throwException(e);
        }
        finally
        {
            lock.unlock();
        }
        watch.stop();
        getLog().info(String.format("[{%s}]{%s}[1/1]任务处理完成，本次耗时:{%s}ms！！！ ", logTraceId, getTaskName(), watch.getLastTaskTimeMillis()));
    }
    
    @SuppressWarnings("deprecation")
    @Override
    public PreAlertObject executeTask(BgWorkingContext args) throws BusinessException
    {
        initializ(args);
        String taskStr = "后台任务-[" + taskName + "]";
        PreAlertObject rtnobj = new PreAlertObject();
        rtnobj.setMsgTitle(taskStr);
        rtnobj.setReturnType(PreAlertReturnType.RETURNMESSAGE);
        rtnobj.setReturnObj(taskStr + "：成功");
        rtnobj.setBusiObj(argsMap);
        StopWatch watch = new StopWatch();
        watch.start();
        
        logTraceId = System.currentTimeMillis();
        try
        {
            getLog().info(taskStr + "-->接受到的参数是..." + JsonUtil.toJSONString(getArgsMap()));
            getLog().info(taskStr + " 开始运行...");
            runing(args);
        }
        catch (Throwable e)
        {
            String msg = StringUtil.toString(args.getKeyMap());
            try
            {
                msg = JsonUtil.compressJson(JsonUtil.toJSONString(msg));
            }
            catch (Exception e1)
            {
                getLog().error(taskStr + " 运行结束！对象转map异常：" + StringUtil.toString(e1));
            }
            String msgStr = taskStr + "出现异常：" + e.getMessage() + "，参数信息信息：{[" + msg + " ]}";
            args.setLogStr(msgStr);
            rtnobj.setBusiObj(e);
            rtnobj.setReturnObj(msgStr);
            getLog().info(msgStr);
            getLog().exception(msgStr, e);
            // 异常抛出
            JudgeAssertUtil.checkAssertDir(PubEnvUtil.equals(PubEnvUtil.TRUE, argsMap.get(checkthrow)), folder, msgStr);
        }
        finally
        {
            gc();
            watch.stop();
            getLog().info(taskStr + " 运行结束！返回信息：" + StringUtil.toString(getMsgList()));
            getLog().info(String.format("[{%s}][1/1]" + taskStr + "完成，本次耗时:{%s}ms！！！ ", logTraceId, watch.getLastTaskTimeMillis()));
            getLog().info(LoggerAbs.getSplitLine());
        }
        
        return rtnobj;
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 这里调用GC，建议重写,在这里清空[变量]<br>
     * 
     * @see <br>
     *      <br>
     * @void <br>
     * @methods pers.bc.utils.yonyou.BackgroundWorkTaskPlugin#gc <br>
     * @author LiBencheng <br>
     * @date Created on 2024-6-26 <br>
     * @time 下午3:54:40 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    protected void gc()
    {
        // 这里调用GC，建议在这里清空[变量]
        // 。。。。。
        
        // 是否调用运行时GC java.lang.Runtime
        if (PubEnvUtil.equals(argsMap.get("isgc"), IPubCons.TRUE) || PubEnvUtil.equals(argsMap.get("isgc"), IPubCons.Y))
            Runtime.getRuntime().gc();
        
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 后台任务初始化，二开重写此方法<br>
     * 
     * @see <br>
     * @param args <br>
     * @void <br>
     * @methods pers.bc.utils.yonyou.BackgroundWorkTaskPlugin#initializ <br>
     * @author LiBencheng <br>
     * @date Created on 2024年1月22日 <br>
     * @time 13:49:06 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    @SuppressWarnings("deprecation")
    protected void initializ(BgWorkingContext args)
    {
        setTaskName(args.getAlertTypeName());
        pk_group = args.getGroupId();
        msgList = new ArrayList();
        argsMap = args.getKeyMap();
        folder += (File.separator + this.getClass().getSimpleName());
        logUtil = LoggerUtil.getInstance(folder);
        InvocationInfo invocationInfo = InvocationInfoUtils.getInvocationInfo();
        invocationInfo.setCallId(taskName + InvocationInfoProxy.getInstance().getCallId());
        // InvocationInfoUtils.setInvocationInfo(invocationInfo);
    }
    
    public void setArgsMap(LinkedHashMap<String, Object> argsMap)
    {
        this.argsMap = argsMap;
    }
    
    public LinkedHashMap<String, Object> getArgsMap()
    {
        return argsMap;
    }
    
    public void setTaskName(String taskName)
    {
        this.taskName = taskName;
    }
    
    public String getTaskName()
    {
        return taskName;
    }
    
    public void setFolder(String folder)
    {
        this.folder = folder;
    }
    
    public void setLog(LoggerUtil logUtil)
    {
        this.logUtil = logUtil;
    }
    
    public LoggerUtil getLog()
    {
        return logUtil;
    }
    
    public List<String> getMsgList()
    {
        return msgList;
    }
    
}
